package com.genersoft.iot.vmp.business;

import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.DeviceAlarm;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.utils.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
@EnableAsync
public class BizAlarmServiceExecutor {

    private final static Logger logger = LoggerFactory.getLogger(BizAlarmServiceExecutor.class);

    @Value("${business.uploadDir}")
    String uploadDir;
    @Value("${server.ip}")
    String serverIp;
    @Value("${server.port}")
    String serverPort;
    @Value("${media.ip}")
    String mediaIp;
    @Value("${media.wanIp}")
    String mediaWanIp;

    @Autowired
    private BizHttpService bizHttpService;

    @Autowired
    private ZLMRESTfulUtils zlmresTfulUtils;

    @Async("commonAsyncPool")
    public void insertAlarm(Device device, DeviceAlarm alarm) {
        // 推流
        String playUrl = "/api/play/" + alarm.getDeviceId() + "/" + alarm.getChannelId();
        String response = bizHttpService.executeLocalGetApi(playUrl);
        String streamId = null, streamUrl = null, snapUrl = null;
        if (response != null) {
            JSONObject jsonObject = JSONObject.parseObject(response);
            if (jsonObject.containsKey("streamId")) {
                streamId = jsonObject.getString("streamId");
                streamUrl = jsonObject.getString("rtmp");
                streamUrl = streamUrl.replace(mediaWanIp, mediaIp);
            } else {
                String msg = jsonObject.getString("msg");
                logger.info(String.format("insert alarm play url fail %s %s %s", alarm.getDeviceId(), alarm.getChannelId(), msg));
            }
        }
        if (streamId != null && streamUrl != null) {
            // 判断流是否存在
            int i = 0;
            boolean streamExist = false;
            while (i < 10) {
                JSONObject jsonObject = zlmresTfulUtils.getMediaList("rtp", "rtsp", streamId);
                if (jsonObject.containsKey("data") && jsonObject.getJSONArray("data").size() > 0) {
                    streamExist = true;
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                ++i;
            }
            if (streamExist) {
                // 截图
                String dateDir = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                String picName = alarm.getSn() + "-" + alarm.getDeviceId() + "-" + alarm.getChannelId() + ".jpg";
                String fileName = dateDir + File.separator + picName;
                String destFile = uploadDir + fileName;
                FileUtil.makeDirs(destFile);
                boolean result = zlmresTfulUtils.getSnap(streamUrl, destFile);
                if (result) {
                    snapUrl = "http://" + serverIp + ":" + serverPort + "/" + fileName;
                } else {
                    logger.info(String.format("insert alarm get snap failure  %s %s", alarm.getDeviceId(), alarm.getChannelId()));
                }

                // 关闭流
                // 判断是否还有人观看
                int totalReaderCount = 0;
                JSONObject mediaJson = zlmresTfulUtils.getMediaList("rtp", "rtmp", streamId);
                if (mediaJson.containsKey("data") && mediaJson.getJSONArray("data").size() > 0) {
                    JSONObject mediaObject = mediaJson.getJSONArray("data").getJSONObject(0);
                    totalReaderCount = mediaObject.getIntValue("totalReaderCount");
                }
                if (totalReaderCount == 0) {
                    String stopUrl = "/api/play/" + streamId + "/stop";
                    bizHttpService.executeLocalPostApi(stopUrl, null);
                }
            } else {
                logger.info(String.format("insert alarm stream not found  %s %s", alarm.getDeviceId(), alarm.getChannelId()));
            }
        }

        if (snapUrl != null) {
            // 转发
            String alarmId = device.getDeviceId() + "-" + System.currentTimeMillis() / 1000;
            String alarmContent = "报警";
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("alarmId", alarmId);
            map.add("alarmTime", alarm.getAlarmTime());
            map.add("deviceName", device.getName());
            map.add("deviceCode", device.getDeviceId());
            map.add("mediaUrl", snapUrl);
            map.add("ip", device.getIp());
            map.add("content", alarmContent);

            String alarmResult = bizHttpService.alarmTransmitPost(map);
            if (alarmResult != null) {
                JSONObject jsonObject = JSONObject.parseObject(alarmResult);
                int status = jsonObject.getIntValue("status");
                String msg = jsonObject.getString("msg");
                logger.info(String.format("alarm transmit result  %s %s status=%s msg=%s", alarm.getDeviceId(), alarm.getChannelId(),
                        String.valueOf(status), msg));
            } else {
                logger.info(String.format("alarm transmit error  %s %s", alarm.getDeviceId(), alarm.getChannelId()));
            }
        } else {
            logger.info(String.format("alarm transmit stop snap url is empty  %s %s", alarm.getDeviceId(), alarm.getChannelId()));
        }
    }
}
